package com.ruoyi.business.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.bizsys.domain.CreditAccount;
import com.ruoyi.bizsys.domain.LoanIou;
import com.ruoyi.bizsys.domain.LoanOrder;
import com.ruoyi.bizsys.service.ICreditAccountService;
import com.ruoyi.bizsys.service.ILoanIouService;
import com.ruoyi.bizsys.service.ILoanOrderService;
import com.ruoyi.business.mapper.LoanMapper;
import com.ruoyi.business.service.ILoanApplyService;
import com.ruoyi.business.service.ILoanService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.Func;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
//@RestController
//@RequestMapping("/retry/v2/")
public class RepeatLoanTask {

    @Autowired
    private LoanMapper loanMapper;

    @Autowired
    private ILoanIouService loanIouService;

    @Autowired
    private ICreditAccountService creditAccountService;

    @Autowired
    private ILoanApplyService iLoanApplyService;

    @Autowired
        private ILoanService loanService;

    @Autowired
    private ILoanOrderService loanOrderService;

    @PostMapping("repeatLoan/{limit}")
    public void repeatLoan(@PathVariable int limit) throws ParseException {

        /**
         *  1.生成LoanOrder
         *  2. 生成贷款合同pdf
         *  3. 生成iou
         *  4.更新CreditAccount
         */
        List<Map<String, Object>> repeatLoans = loanMapper.getRepeatLoans(limit);

        for (Map<String, Object> map : repeatLoans) {

            Object id = map.get("id");
            String custNo = map.get("cust_no").toString();
            String reference = map.get("reference").toString();
            String amount = map.get("amount").toString();
            String transferDate = map.get("transfer_date").toString();
            try {

                doMain(custNo,transferDate,amount,reference);

                loanMapper.upRepeatLoanState(id);
            } catch (Exception e) {
                log.error("重复放款异常", e);

            }


        }

    }

    @Transactional
    public void doMain(String custNo, String transferDate, String amount, String reference) throws ParseException {
        // 生成贷款合同
        //String contractNo = IdUtils.generateContractNo();
        LoanOrder loanOrder = loanMapper.getLoanorderTemp(custNo, transferDate);
        if (Func.isEmpty(loanOrder)){
            loanOrder = loanMapper.getLoanorderTemp2(custNo);
        }
        loanOrder.setId(null);
        loanOrder.setLoanSerialNo(IdUtils.reqId());

        loanOrder.setLoanStatus(4);
        loanOrder.setLoanAmt(new BigDecimal(amount));

        loanOrder.setTotalAmt(new BigDecimal(amount));
        //待定
        loanOrder.setPayTransSerialNo(reference);
        loanOrder.setRemark("重复放款订单");
        loanOrder.setCreateTime(DateUtils.parseDate(transferDate));
        loanOrder.setUpdateTime(DateUtils.parseDate(transferDate));
        //创建合同
        String contractPdf = loanService.createContractPdf(loanOrder);
        loanOrder.setContractNo(contractPdf);

        //写0
        loanOrder.setServiceFee(new BigDecimal(BigInteger.ZERO));
        loanOrder.setInterestAmt(new BigDecimal(BigInteger.ZERO));

        loanOrderService.insertLoanOrder(loanOrder);

        //操作iou
        LoanIou loanIou = this.opLoanIout(loanOrder);
        //更新CreditAccount
        this.opAccount(loanIou, custNo);
    }

    private LoanIou opLoanIout(LoanOrder loanOrder) throws ParseException {
        LoanIou loanIou = new LoanIou();
        BeanUtils.copyProperties(loanOrder, loanIou);
        loanIou.setLoanPrincipal(loanOrder.getLoanAmt());
        loanIou.setIouStatus(LoanIou.LOAN_IOU_STATUS_NORMAL);
        loanIou.setRepayDate(loanOrder.getRepayDate());
        loanIou.setRemark("重复放款订单");
        loanIou.setLateFee(new BigDecimal(BigInteger.ZERO));
        loanIou.setOverdueAmount(new BigDecimal(BigInteger.ZERO));

        //计算滞纳金、逾期金额
        Date repayDate = DateUtils.parseDate(loanIou.getRepayDate(), DateUtils.YYYY_MM_DD_SLASH);
        //逾期天数计算
        Instant repayDateInstant = repayDate.toInstant();
        Instant batchDateInstant = new Date().toInstant();
        long daysDiff = Duration.between(repayDateInstant, batchDateInstant).toDays();

        //判断是否在宽限期
        int lateFeeGracePeriod = loanIou.getLateFeeGracePeriod();
        if (daysDiff > lateFeeGracePeriod) {
            daysDiff = daysDiff - lateFeeGracePeriod;
        }
        loanIou.setIouStatus(0);
        loanIou.setRepaidInterest(new BigDecimal(BigInteger.ZERO));
        loanIou.setRepaidLateFee(new BigDecimal(BigInteger.ZERO));
        loanIou.setRepaidPrincipal(new BigDecimal(BigInteger.ZERO));

        if (daysDiff > 0) {
            BigDecimal principalNeed = loanIou.getLoanPrincipal().subtract(loanIou.getRepaidPrincipal());//本金还需要还的

            //滞纳金日费率
            BigDecimal dateLateFee = loanIou.getDateLateFee();

            //费率计算的最大天数
            if (daysDiff <= loanIou.getLateFeeMaxDays()) {
                //逾期金额
                int backDays = DateUtils.daysBetween(DateUtils.parseDate(loanIou.getRepayDate()), DateUtils.getNowDate());
                BigDecimal lateFee = principalNeed.multiply(dateLateFee).multiply(new BigDecimal(backDays));
                loanIou.setLateFee(loanIou.getLateFee().add(lateFee));

                //逾期总金额
                loanIou.setOverdueAmount(loanIou.getLateFee().add(loanIou.getLoanAmt()));
            }
            loanIou.setIouStatus(2);
        }
        loanIouService.insertLoanIou(loanIou);

        return loanIou;
    }

    private void opAccount(LoanIou loanIou, String custNo) {

        // 不需要解冻额度 服务费 滞纳金 利息 逾期金额  增加在贷额度
        CreditAccount creditAccount = creditAccountService.getOne(new QueryWrapper<CreditAccount>().eq("cust_no", custNo));
        CreditAccount nweObj = new CreditAccount();
        nweObj.setId(creditAccount.getId());
        //滞纳金
        nweObj.setLateFee(creditAccount.getLateFee().add(loanIou.getLateFee()));
        //逾期金额
        nweObj.setOverdueAmount(loanIou.getOverdueAmount().add(creditAccount.getOverdueAmount()));
        //增加在贷额度
        nweObj.setLoanQuota(creditAccount.getLoanQuota().add(loanIou.getLoanAmt()));
        //放款本金
        nweObj.setLoanPrincipal(creditAccount.getLoanPrincipal().add(loanIou.getLoanAmt()));
        //是否在贷
        nweObj.setOnLoan("1");
        creditAccountService.updateById(nweObj);

    }


}
